<?php

namespace App\Domain\Permissions\Dao;

use App\Domain\Permissions\Models\PermissionsModel;

class PermissionsDao
{
    const DEFAULT_CHILDREN_NAME = 'children';

    /**
     * 获取菜单权限树
     * @param array $columns
     * @param array $typeList
     * @param string $childrenName
     * @param bool $showButton
     * @param string $appName
     * @return array
     */
    public function getTree($columns = ['*'], $typeList, $childrenName = self::DEFAULT_CHILDREN_NAME, $showButton = false, $appName = 'pc')
    {
        return self::getSons(0, $typeList, $columns, $childrenName, $showButton, $appName);
    }


    /**
     * 获取菜单权限树-递归
     * @param int $pid
     * @param array $typeList
     * @param array $columns
     * @param string $childrenName
     * @param bool $showButton
     * @param string $appName
     * @return array
     */
    protected function getSons($pid = 0, $typeList = [1], $columns = ['*'], $childrenName = self::DEFAULT_CHILDREN_NAME, $showButton = false, $appName = 'pc')
    {
        $sons = [];
        $list = PermissionsModel::select($columns)->where('enable', 1)->where('pid', $pid)->where(function ($query) use ($showButton, $typeList) {
            if (!$showButton) {
                $query->whereIn('type', $typeList);
            }
        })->where(function ($query) use ($appName) {
            if ($appName) {
                $query->where('app_name', $appName);
            }
        })->orderBy('sort')->get()->toArray();
        foreach ($list as $item) {
            $son = $item;
            $son[$childrenName] = self::getSons($item['id'], $typeList, $columns, $childrenName, $showButton, $appName);
            $sons[] = $son;
        }
        return $sons;
    }

    /**
     * 权限树子设置用户是否有权限字段-递归
     * @param $permissionList
     * @param array $tree
     * @param string $childrenName
     * @param $typeList //需要显示的类型数组  [1]  or [1,2]
     * @param $hasAllAuthority
     * @param $parentHasAuthority //子节点有权限则父节点必然有权限
     * @return array
     */
    protected function setSonsAuthorityAndFilterType($permissionList, array $tree, $childrenName = self::DEFAULT_CHILDREN_NAME, $typeList, &$hasAllAuthority, &$parentHasAuthority = 0)
    {
        $new_tree = [];
        foreach ($tree as $item) {
            $sonHasAuthority = 0;
            $new_tree_item = $item;
            if (!empty($item[$childrenName])) {
                $new_tree_item[$childrenName] = self::setSonsAuthorityAndFilterType($permissionList, $item[$childrenName], $childrenName, $typeList, $hasAllAuthority, $sonHasAuthority);
            } else {
                $new_tree_item[$childrenName] = [];
                //最后一个节点，还需要去数据库查询，有没有子节点的权限
            }
            //父节点自动增加权限  子节点只要一个有权限，父节点（当前节点）就有权限
            if ($sonHasAuthority == 1) {
                $new_tree_item['hasAuthority'] = 1;
            } else {
                $new_tree_item['hasAuthority'] = in_array($item['id'], $permissionList) ? 1 : 0;
            }
            //一个子节点有权限，则父节点有权限
            if ($new_tree_item['hasAuthority'] == 1) {
                $parentHasAuthority = 1;
            }

            //是否拥有所有权限    当前节点没有权限，那么就不拥有
            if ($new_tree_item['hasAuthority'] == 0) {
                $hasAllAuthority = 0;
            }
            //过滤不在允许类型中的数组 主要是为了过滤按钮
            if (in_array((int)$new_tree_item['type'], $typeList)) {
                $new_tree[] = $new_tree_item;
            }
        }
        return $new_tree;
    }

    /**
     * 权限树设置用户是否有权限字段
     * @param  $permissionList
     * @param array $tree
     * @param string $childrenName
     * @param $typeList
     * @param $hasAllAuthority
     * @return array
     */
    public function setHasAuthorityAndFilterType($permissionList, array $tree, $childrenName = self::DEFAULT_CHILDREN_NAME, $typeList, &$hasAllAuthority)
    {
        $hasAllAuthority = true;
        return self::setSonsAuthorityAndFilterType($permissionList, $tree, $childrenName, $typeList, $hasAllAuthority);
    }

    public function getPermissionByName(string $permissionName)
    {
        return PermissionsModel::query()->where("name", $permissionName)->first();
    }

    public function getPermissionByAppName(string $appName)
    {
        return PermissionsModel::query()->where("app_name", $appName)->get();
    }
}
